home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Travel to Space
/
Travel to Space.iso
/
dos_prog
/
astronmy
/
epherms
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-09-13
|
26KB
|
965 lines
/* main "ephem" program.
* -------------------------------------------------------------------
* Copyright (c) 1990 by Elwood Charles Downey
*
* Permission is granted to make and distribute copies of this program
* free of charge, provided the copyright notice and this permission
* notice are preserved on all copies. All other rights reserved.
* -------------------------------------------------------------------
* set options.
* init screen and circumstances.
* enter infinite loop updating screen and allowing operator input.
*/
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <math.h>
#ifdef VMS
#include <stdlib.h>
#endif
#include "astro.h"
#include "circum.h"
#include "screen.h"
extern char *strncpy();
extern char *getenv();
/* shorthands for fields of a Now structure, now.
* first undo the ones for a Now pointer from circum.h.
*/
#undef mjd
#undef lat
#undef lng
#undef tz
#undef temp
#undef pressure
#undef height
#undef epoch
#undef tznm
#define mjd now.n_mjd
#define lat now.n_lat
#define lng now.n_lng
#define tz now.n_tz
#define temp now.n_temp
#define pressure now.n_pressure
#define height now.n_height
#define epoch now.n_epoch
#define tznm now.n_tznm
static jmp_buf fpe_err_jmp; /* used to recover from SIGFPE */
static char *cfgfile; /* !0 if -c used */
static char cfgdef[] = "ephem.cfg"; /* default configuration file name */
static Now now; /* where when and how, right now */
static double tminc; /* hrs to inc time by each loop; RTC means use clock */
static int nstep; /* steps to go before stopping */
static int spause; /* secs to pause between steps */
static int optwi; /* set when want to display dawn/dusk/len-of-night */
static int oppl; /* mask of (1<<planet) bits; set when want to show it */
main (ac, av)
int ac;
char *av[];
{
void bye();
void on_fpe();
static char freerun[] =
"Running... press any key to stop to make changes.";
static char prmpt[] =
"Move to another field, RETURN to change this field, ? for help, or q to run";
static char hlp[] =
"arrow keys move to field; any key stops running; ^d exits; ^l redraws";
int curr = R_NSTEP, curc = C_NSTEPV; /* must start somewhere */
int sflag = 0; /* not silent, by default */
int one = 1; /* use a variable so optimizer doesn't get disabled */
int srchdone = 0; /* true when search funcs say so */
int newcir = 2; /* set when circumstances change - means don't tminc */
while ((--ac > 0) && (**++av == '-')) {
char *s;
for (s = *av+1; *s != '\0'; s++)
switch (*s) {
case 's': /* no credits "silent" (don't publish this) */
sflag++;
break;
case 'c': /* set name of config file to use */
if (--ac <= 0) usage("-c but no config file");
cfgfile = *++av;
break;
case 'd': /* set alternate database file name */
if (--ac <= 0) usage("-d but no database file");
obj_setdbfilename (*++av);
break;
default:
usage("Bad - option");
}
}
if (!sflag)
credits();
/* fresh screen.
* crack config file, THEN args so args may override.
*/
c_erase();
read_cfgfile ();
read_fieldargs (ac, av);
/* set up to clean up screen and tty if interrupted.
* also set up to stop if get floating error.
*/
(void) signal (SIGINT, bye);
(void) signal (SIGFPE, on_fpe);
/* update screen forever (until QUIT) */
while (one) {
/* if get a floating error, longjmp() here and stop looping */
if (setjmp (fpe_err_jmp))
nstep = 0;
else {
nstep -= 1;
/* recalculate everything and update all the fields */
redraw_screen (newcir);
mm_newcir (0);
/* let searching functions change tminc and check for done */
srchdone = srch_eval (mjd, &tminc) < 0;
print_tminc(0); /* to show possibly new search increment */
/* update plot and listing files, now that all fields are up
* to date and search function has been evaluated.
*/
plot();
listing();
/* handle spause if we are really looping */
if (nstep > 0)
slp_sync();
}
/* stop loop to allow op to change parameters:
* if a search evaluation converges (or errors out),
* or if steps are done,
* or if op hits any key.
*/
newcir = 0;
if (srchdone || nstep <= 0 || (chk_char()==0 && read_char()!=0)) {
int fld;
/* update screen with the current stuff if stopped during
* unattended plotting or listing since last redraw_screen()
* didn't.
*/
if ((plot_ison() || listing_ison()) && nstep > 0)
redraw_screen (1);
/* return nstep to default of 1 */
if (nstep <= 0) {
nstep = 1;
print_nstep (0);
}
/* change fields until END.
* update all time fields if any are changed
* and print NEW CIRCUMSTANCES if any have changed.
* QUIT causes bye() to be called and we never return.
*/
while(fld = sel_fld(curr,curc,alt_menumask()|F_CHG,prmpt,hlp)) {
if (chg_fld ((char *)0, fld)) {
mm_now (&now, 1);
mm_newcir(1);
newcir = 1;
}
curr = unpackr (fld);
curc = unpackc (fld);
}
if (nstep > 1)
f_prompt (freerun);
}
/* increment time only if op didn't change cirumstances */
if (!newcir)
inc_mjd (&now, tminc);
}
return (0);
}
/* read in ephem's configuration file, if any.
* if errors in file, call usage() (which exits).
* if use -d, require it; else try $EPHEMCFG and ephem.cfg but don't
* complain if can't find these since, after all, one is not required.
* skip blank lines and lines that begin with '#', '*', ' ' or '\t'.
*/
static
read_cfgfile()
{
char buf[128];
FILE *fp;
char *fn;
/* open the config file.
* only REQUIRED if used -d option.
* if succcessful, fn points to file name.
*/
if (cfgfile) {
fn = cfgfile;
fp = fopen (fn, "r");
if (!fp) {
(void) sprintf (buf, "Can not open %s", fn);
usage (buf); /* does not return */
}
} else {
fn = getenv ("EPHEMCFG");
if (!fn)
fn = cfgdef;
}
fp = fopen (fn, "r");
if (!fp)
return; /* oh well; after all, it's not required */
while (fgets (buf, sizeof(buf), fp)) {
switch (buf[0]) {
case '#': case '*': case ' ': case '\t': case '\n':
continue;
}
buf[strlen(buf)-1] = '\0'; /* discard trailing \n */
if (crack_fieldset (buf) < 0) {
char why[NC];
(void) sprintf (why, "Bad field spec in %s: %s\n", fn, buf);
usage (why);
}
}
(void) fclose (fp);
}
/* draw all the stuff on the screen, using the current menu.
* if how_much == 0 then just update fields that need it;
* if how_much == 1 then redraw all fields;
* if how_much == 2 then erase the screen and redraw EVERYTHING.
*/
redraw_screen (how_much)
int how_much;
{
if (how_much == 2)
c_erase();
/* print the single-step message if this is the last loop */
if (nstep < 1)
print_updating();
if (how_much == 2) {
mm_borders();
mm_labels();
srch_prstate(1);
plot_prstate(1);
listing_prstate(1);
alt_labels();
}
/* if just updating changed fields while plotting or listing
* unattended then suppress most screen updates except
* always show nstep to show plot loops to go and
* always show tminc to show search convergence progress.
*/
print_nstep(how_much);
print_tminc(how_much);
print_spause(how_much);
if (how_much == 0 && (plot_ison() || listing_ison()) && nstep > 0)
f_off();
/* print all the time-related fields */
mm_now (&now, how_much);
if (optwi)
mm_twilight (&now, how_much);
/* print solar system body info */
print_bodies (how_much);
f_on();
}
/* clean up and exit.
*/
void
bye()
{
c_erase();
byetty();
exit (0);
}
/* this gets called when a floating point error occurs.
* we force a jump back into main() with looping terminated.
*/
static
void
on_fpe()
{
(void) signal (SIGFPE, on_fpe);
f_msg ("Floating point error has occurred - computations aborted.");
longjmp (fpe_err_jmp, 1);
}
usage(why)
char *why;
{
/* don't advertise -s (silent) option */
c_erase();
f_string (1, 1, why);
f_string (2, 1,
"usage: [-c <configfile>] [-d <database>] [field=value ...]\r\n");
byetty();
exit (1);
}
/* process the field specs from the command line.
* if trouble call usage() (which exits).
*/
static
read_fieldargs (ac, av)
int ac; /* number of such specs */
char *av[]; /* array of strings in form <field_name value> */
{
while (--ac >= 0) {
char *fs = *av++;
if (crack_fieldset (fs) < 0) {
char why[NC];
(void) sprintf (why, "Bad command line spec: %.*s",
sizeof(why)-26, fs);
usage (why);
}
}
}
/* process a field spec in buf, either from config file or argv.
* return 0 if recognized ok, else -1.
*/
static
crack_fieldset (buf)
char *buf;
{
if (strncmp ("LAT", buf, 3) == 0)
(void) chg_fld (buf+4, rcfpack (R_LAT,C_LATV,0));
else if (strncmp ("LONG", buf, 4) == 0)
(void) chg_fld (buf+5, rcfpack (R_LONG,C_LONGV,0));
else if (strncmp ("UT", buf, 2) == 0)
(void) chg_fld (buf+3, rcfpack (R_UT,C_UTV,0));
else if (strncmp ("UD", buf, 2) == 0)
(void) chg_fld (buf+3, rcfpack (R_UD,C_UD,0));
else if (strncmp ("TZONE", buf, 5) == 0)
(void) chg_fld (buf+6, rcfpack (R_TZONE,C_TZONEV,0));
else if (strncmp ("TZNAME", buf, 6) == 0)
(void) chg_fld (buf+7, rcfpack (R_TZN,C_TZN,0));
else if (strncmp ("HEIGHT", buf, 6) == 0)
(void) chg_fld (buf+7, rcfpack (R_HEIGHT,C_HEIGHTV,0));
else if (strncmp ("NSTEP", buf, 5) == 0)
(void) chg_fld (buf+6, rcfpack (R_NSTEP,C_NSTEPV,0));
else if (strncmp ("PAUSE", buf, 5) == 0)
(void) chg_fld (buf+6, rcfpack (R_PAUSE,C_PAUSEV,0));
else if (strncmp ("STPSZ", buf, 5) == 0)
(void) chg_fld (buf+6, rcfpack (R_STPSZ,C_STPSZV,0));
else if (strncmp ("TEMP", buf, 4) == 0)
(void) chg_fld (buf+5, rcfpack (R_TEMP,C_TEMPV,0));
else if (strncmp ("PRES", buf, 4) == 0)
(void) chg_fld (buf+5, rcfpack (R_PRES,C_PRESV,0));
else if (strncmp ("EPOCH", buf, 5) == 0)
(void) chg_fld (buf+6, rcfpack (R_EPOCH,C_EPOCHV,0));
else if (strncmp ("JD", buf, 2) == 0)
(void) chg_fld (buf+3, rcfpack (R_JD,C_JDV,0));
else if (strncmp ("OBJX", buf, 4) == 0)
obj_filelookup (OBJX, buf+5);
else if (strncmp ("OBJY", buf, 4) == 0)
obj_filelookup (OBJY, buf+5);
else if (strncmp ("PROPTS", buf, 6) == 0) {
char *bp = buf+7;
if (buf[6] != '+')
optwi = oppl = 0;
while (*bp)
switch (*bp++) {
case 'T': optwi = 1; break;
case 'S': oppl |= (1<<SUN); break;
case 'M': oppl |= (1<<MOON); break;
case 'e': oppl |= (1<<MERCURY); break;
case 'v': oppl |= (1<<VENUS); break;
case 'm': oppl |= (1<<MARS); break;
case 'j': oppl |= (1<<JUPITER); break;
case 's': oppl |= (1<<SATURN); break;
case 'u': oppl |= (1<<URANUS); break;
case 'n': oppl |= (1<<NEPTUNE); break;
case 'p': oppl |= (1<<PLUTO); break;
case 'x': oppl |= (1<<OBJX); obj_on(OBJX); break;
case 'y': oppl |= (1<<OBJY); obj_on(OBJY); break;
}
} else if (strncmp ("MENU", buf, 4) == 0) {
if (strncmp (buf+5, "DATA", 4) == 0)
altmenu_init (F_MNU1);
else if (strncmp (buf+5, "RISET", 5) == 0)
altmenu_init (F_MNU2);
else if (strncmp (buf+5, "SEP", 3) == 0)
altmenu_init (F_MNU3);
} else
return (-1);
return (0);
}
/* change the field at rcpk according to the optional string input at bp.
* if bp is != 0 use it, else issue read_line() and use buffer.
* then sscanf the buffer and update the corresponding (global) variable(s)
* or do whatever a pick at that field should do.
* return 1 if we change a field that invalidates any of the times or
* to update all related fields.
*/
static
chg_fld (bp, rcpk)
char *bp;
int rcpk;
{
char buf[NC];
int deghrs = 0, mins = 0, secs = 0;
int new = 0;
/* switch on just the row/col portion */
switch (unpackrc(rcpk)) {
case rcfpack (R_ALTM, C_ALTM, 0):
if (altmenu_setup() == 0) {
print_updating();
alt_nolabels();
clrall_bodies();
alt_labels();
print_bodies(1);
}
break;
case rcfpack (R_JD, C_JDV, 0):
if (!bp) {
static char p[] = "Julian Date (or n for Now): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else
mjd = atof(bp) - 2415020L;
set_t0 (&now);
new = 1;
break;
case rcfpack (R_UD, C_UD, 0):
if (!bp) {
static char p[] = "utc date (m/d/y, or year.d, or n for Now): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else {
if (decimal_year(bp)) {
double y = atof (bp);
year_mjd (y, &mjd);
} else {
double day, newmjd0;
int month, year;
mjd_cal (mjd, &month, &day, &year); /* init with now */
f_sscandate (bp, &month, &day, &year);
cal_mjd (month, day, year, &newmjd0);
/* if don't give a fractional part to days
* then retain current hours.
*/
if ((long)day == day)
mjd = newmjd0 + mjd_hr(mjd)/24.0;
else
mjd = newmjd0;
}
}
set_t0 (&now);
new = 1;
break;
case rcfpack (R_UT, C_UTV, 0):
if (!bp) {
static char p[] = "utc time (h:m:s, or n for Now): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else {
double newutc = (mjd-mjd_day(mjd)) * 24.0;
f_dec_sexsign (newutc, °hrs, &mins, &secs);
f_sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &newutc);
mjd = mjd_day(mjd) + newutc/24.0;
}
set_t0 (&now);
new = 1;
break;
case rcfpack (R_LD, C_LD, 0):
if (!bp) {
static char p[] = "local date (m/d/y, or year.d, n for Now): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else {
if (decimal_year(bp)) {
double y = atof (bp);
year_mjd (y, &mjd);
mjd += tz/24.0;
} else {
double day, newlmjd0;
int month, year;
mjd_cal (mjd-tz/24.0, &month, &day, &year); /* now */
f_sscandate (bp, &month, &day, &year);
cal_mjd (month, day, year, &newlmjd0);
/* if don't give a fractional part to days
* then retain current hours.
*/
if ((long)day == day)
mjd = newlmjd0 + mjd_hr(mjd-tz/24.0)/24.0;
else
mjd = newlmjd0;
mjd += tz/24.0;
}
}
set_t0 (&now);
new = 1;
break;
case rcfpack (R_LT, C_LT, 0):
if (!bp) {
static char p[] = "local time (h:m:s, or n for Now): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else {
double newlt = (mjd-mjd_day(mjd)) * 24.0 - tz;
range (&newlt, 24.0);
f_dec_sexsign (newlt, °hrs, &mins, &secs);
f_sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &newlt);
mjd = mjd_day(mjd-tz/24.0) + (newlt + tz)/24.0;
}
set_t0 (&now);
new = 1;
break;
case rcfpack (R_LST, C_LSTV, 0):
if (!bp) {
static char p[] = "local sidereal time (h:m:s, or n for Now): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else {
double lst, utc;
now_lst (&now, &lst);
f_dec_sexsign (lst, °hrs, &mins, &secs);
f_sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &lst);
lst -= radhr(lng); /* convert to gst */
range (&lst, 24.0);
gst_utc (mjd_day(mjd), lst, &utc);
mjd = mjd_day(mjd) + utc/24.0;
}
set_t0 (&now);
new = 1;
break;
case rcfpack (R_TZN, C_TZN, 0):
if (!bp) {
static char p[] = "timezone abbreviation (3 char max): ";
f_prompt (p);
if (read_line (buf, 3) <= 0)
break;
bp = buf;
}
(void) strncpy (tznm, bp, sizeof(tznm)-1);
new = 1;
break;
case rcfpack (R_TZONE, C_TZONEV, 0):
if (!bp) {
static char p[] = "hours behind utc: ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
f_dec_sexsign (tz, °hrs, &mins, &secs);
f_sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &tz);
new = 1;
break;
case rcfpack (R_LONG, C_LONGV, 0):
if (!bp) {
static char p[] = "longitude (+ west) (d:m:s): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
f_dec_sexsign (-raddeg(lng), °hrs, &mins, &secs);
f_sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &lng);
lng = degrad (-lng); /* want - radians west */
new = 1;
break;
case rcfpack (R_LAT, C_LATV, 0):
if (!bp) {
static char p[] = "latitude (+ north) (d:m:s): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
f_dec_sexsign (raddeg(lat), °hrs, &mins, &secs);
f_sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &lat);
lat = degrad (lat);
new = 1;
break;
case rcfpack (R_HEIGHT, C_HEIGHTV, 0):
if (!bp) {
static char p[] = "height above sea level (ft): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
(void) sscanf (bp, "%lf", &height);
height /= 2.093e7; /* convert ft to earth radii above sea level */
new = 1;
break;
case rcfpack (R_NSTEP, C_NSTEPV, 0):
if (!bp) {
static char p[] = "number of steps to run: ";
f_prompt (p);
if (read_line (buf, 8) <= 0)
break;
bp = buf;
}
(void) sscanf (bp, "%d", &nstep);
print_nstep (0);
break;
case rcfpack (R_PAUSE, C_PAUSEV, 0):
if (!bp) {
static char p[] = "seconds to pause between steps: ";
f_prompt (p);
if (read_line (buf, 8) <= 0)
break;
bp = buf;
}
(void) sscanf (bp, "%d", &spause);
print_spause (0);
break;
case rcfpack (R_TEMP, C_TEMPV, 0):
if (!bp) {
static char p[] = "temperature (deg.F): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
(void) sscanf (bp, "%lf", &temp);
temp = 5./9.*(temp - 32.0); /* want degs C */
new = 1;
break;
case rcfpack (R_PRES, C_PRESV, 0):
if (!bp) {
static char p[] =
"atmos pressure (in. Hg; 0 for no refraction correction): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
(void) sscanf (bp, "%lf", &pressure);
pressure *= 33.86; /* want mBar */
new = 1;
break;
case rcfpack (R_EPOCH, C_EPOCHV, 0):
if (!bp) {
static char p[] = "epoch (year, or e for Equinox of Date): ";
f_prompt (p);
if (read_line (buf, PW-strlen(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'e' || bp[0] == 'E')
epoch = EOD;
else {
double e;
e = atof(bp);
year_mjd (e, &epoch);
}
new = 1;
break;
case rcfpack (R_STPSZ, C_STPSZV, 0):
if (!bp) {
static char p[] =
"step size increment (h:m:s, or <x>d for x days, or r for RTC): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'r' || bp[0] == 'R')
tminc = RTC;
else {
int last = strlen (bp) - 1;
if (bp[last] == 'd') {
/* ends in d so treat as a number of days */
double x;
(void) sscanf (bp, "%lf", &x);
tminc = x * 24.0;
} else {
if (tminc == RTC)
deghrs = mins = secs = 0;
else
f_dec_sexsign (tminc, °hrs, &mins, &secs);
f_sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &tminc);
}
}
print_tminc(0);
set_t0 (&now);
break;
case rcfpack (R_PLOT, C_PLOT, 0):
plot_setup();
if (plot_ison())
new = 1;
break;
case rcfpack (R_LISTING, C_LISTING, 0):
listing_setup();
if (listing_ison())
new = 1;
break;
case rcfpack (R_WATCH, C_WATCH, 0):
watch (&now, tminc, oppl);
/* set new reference time to what watch left it.
* no need to set new since watch just did a redraw.
*/
set_t0 (&now);
break;
case rcfpack (R_DAWN, C_DAWN, 0):
case rcfpack (R_DUSK, C_DUSK, 0):
case rcfpack (R_LON, C_LON, 0):
if (optwi ^= 1) {
print_updating();
mm_twilight (&now, 1);
} else {
f_blanks (R_DAWN, C_DAWNV, 5);
f_blanks (R_DUSK, C_DUSKV, 5);
f_blanks (R_LON, C_LONV, 5);
}
break;
case rcfpack (R_SRCH, C_SRCH, 0):
srch_setup();
if (srch_ison())
new = 1;
break;
case rcfpack (R_SUN, C_OBJ, 0):
if ((oppl ^= (1<<SUN)) & (1<<SUN)) {
print_updating();
alt_body (SUN, 1, &now);
} else
alt_nobody (SUN);
break;
case rcfpack (R_MOON, C_OBJ, 0):
if ((oppl ^= (1<<MOON)) & (1<<MOON)) {
print_updating();
alt_body (MOON, 1, &now);
} else
alt_nobody (MOON);
break;
case rcfpack (R_MERCURY, C_OBJ, 0):
if ((oppl ^= (1<<MERCURY)) & (1<<MERCURY)) {
print_updating();
alt_body (MERCURY, 1, &now);
} else
alt_nobody (MERCURY);
break;
case rcfpack (R_VENUS, C_OBJ, 0):
if ((oppl ^= (1<<VENUS)) & (1<<VENUS)) {
print_updating();
alt_body (VENUS, 1, &now);
} else
alt_nobody (VENUS);
break;
case rcfpack (R_MARS, C_OBJ, 0):
if ((oppl ^= (1<<MARS)) & (1<<MARS)) {
print_updating();
alt_body (MARS, 1, &now);
} else
alt_nobody (MARS);
break;
case rcfpack (R_JUPITER, C_OBJ, 0):
if ((oppl ^= (1<<JUPITER)) & (1<<JUPITER)) {
print_updating();
alt_body (JUPITER, 1, &now);
} else
alt_nobody (JUPITER);
break;
case rcfpack (R_SATURN, C_OBJ, 0):
if ((oppl ^= (1<<SATURN)) & (1<<SATURN)) {
print_updating();
alt_body (SATURN, 1, &now);
} else
alt_nobody (SATURN);
break;
case rcfpack (R_URANUS, C_OBJ, 0):
if ((oppl ^= (1<<URANUS)) & (1<<URANUS)) {
print_updating();
alt_body (URANUS, 1, &now);
} else
alt_nobody (URANUS);
break;
case rcfpack (R_NEPTUNE, C_OBJ, 0):
if ((oppl ^= (1<<NEPTUNE)) & (1<<NEPTUNE)) {
print_updating();
alt_body (NEPTUNE, 1, &now);
} else
alt_nobody (NEPTUNE);
break;
case rcfpack (R_PLUTO, C_OBJ, 0):
if ((oppl ^= (1<<PLUTO)) & (1<<PLUTO)) {
print_updating();
alt_body (PLUTO, 1, &now);
} else
alt_nobody (PLUTO);
break;
case rcfpack (R_OBJX, C_OBJ, 0):
/* this might change which columns are used so erase all when
* returns and redraw if still on.
*/
obj_setup (OBJX);
alt_nobody (OBJX);
if (obj_ison (OBJX)) {
oppl |= 1 << OBJX;
print_updating();
alt_body (OBJX, 1, &now);
} else
oppl &= ~(1 << OBJX); /* already erased; just clear flag */
break;
case rcfpack (R_OBJY, C_OBJ, 0):
/* this might change which columns are used so erase all when
* returns and redraw if still on.
*/
obj_setup (OBJY);
alt_nobody (OBJY);
if (obj_ison (OBJY)) {
oppl |= 1 << OBJY;
print_updating();
alt_body (OBJY, 1, &now);
} else
oppl &= ~(1 << OBJY); /* already erased; just clear flag */
break;
}
return (new);
}
static
print_tminc(force)
int force;
{
static double last = -123.456; /* anything unlikely */
if (force || tminc != last) {
if (tminc == RTC)
f_string (R_STPSZ, C_STPSZV, " RT CLOCK");
else if (fabs(tminc) >= 24.0)
f_double (R_STPSZ, C_STPSZV, "%6.4g dy", tminc/24.0);
else
f_signtime (R_STPSZ, C_STPSZV, tminc);
last = tminc;
}
}
static
print_bodies (force)
int force;
{
int p;
for (p = nxtbody(-1); p != -1; p = nxtbody(p))
if (oppl & (1<<p))
alt_body (p, force, &now);
}
static
clrall_bodies ()
{
int p;
for (p = nxtbody(-1); p != -1; p = nxtbody(p))
if (oppl & (1<<p))
alt_nobody (p);
}
print_updating()
{
f_prompt ("Updating...");
}
static
print_nstep(force)
int force;
{
static int last;
if (force || nstep != last) {
char buf[16];
(void) sprintf (buf, "%8d", nstep);
f_string (R_NSTEP, C_NSTEPV, buf);
last = nstep;
}
}
static
print_spause(force)
int force;
{
static int last;
if (force || spause != last) {
char buf[16];
(void) sprintf (buf, "%8d", spause);
f_string (R_PAUSE, C_PAUSEV, buf);
last = spause;
}
}
/* if not plotting or searching then sleep spause seconds.
* if time is being based on the real-time clock, sync on the next
* integral multiple of spause seconds after the minute.
* check for keyboard action once each second to let it break out early.
*/
slp_sync()
{
if (spause > 0 && !plot_ison() && !srch_ison()) {
extern long time();
int n= (tminc == RTC) ? spause - (time((long *)0)%spause) : spause;
while (--n >= 0)
if (chk_char() == 0)
break;
else
(void) sleep (1);
}
}